import { Directive, ElementRef, Renderer, OnDestroy, OnInit, AfterViewInit, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[draggable]'
})
export class DraggableDirective implements OnDestroy, OnInit, AfterViewInit {
  private dragElement: any;
  private pos1 = 0;
  private pos2 = 0;
  private pos3 = 0;
  private pos4 = 0;

  private canDrag = true;

  @Input('draggable')
  set draggable(val: any){
    if (val === undefined || val === null || val === '') {
      return;
    }

    this.canDrag = !!val;
  }

  private mustBePosition: Array<string> = ['absolute', 'fixed', 'relative'];

  constructor(private el: ElementRef, private renderer: Renderer) {
  }

  ngOnInit(): void {
    this.el.nativeElement['style'].cursor = 'move';

    this.dragElement = this.el.nativeElement['parentElement']['parentElement']['parentElement'];
    this.dragElement['style'].position = 'absolute';
  }

  ngAfterViewInit() {
  }

  ngOnDestroy(): void {
  }

  @HostListener('mousedown', ['$event'])
  onDragStart(event: MouseEvent) {
    this.pos3 = event.clientX;
    this.pos4 = event.clientY;
    document.onmouseup = evt => {
      this.onDragEnd(evt);
    };

    document.onmousemove = evt => {
      this.onDrag(evt);
    };
  }

  onDrag(event: MouseEvent) {
    this.pos1 = this.pos3 - event.clientX;
    this.pos2 = this.pos4 - event.clientY;
    this.pos3 = event.clientX;
    this.pos4 = event.clientY;

    this.dragElement['style'].top = (this.dragElement.offsetTop - this.pos2) + 'px';
    this.dragElement['style'].left = (this.dragElement.offsetLeft - this.pos1) + 'px';
  }

  onDragEnd(event: MouseEvent) {
    document.onmouseup = null;
    document.onmousemove = null;
  }
}
